x <- c(1, 2, 3)
“Crée un objet nommé ‘x’, contenant les valeurs 1, 2 et 3” ou plus précisément :
Crée un objet de type vecteur c(1, 2, 3).
Associe cet objet à un nom x.
x <- c(1, 2, 3) y <- x
lobstr::obj_addr(x)
#> [1] "0x55e32383c928"
lobstr::obj_addr(y)
#> [1] "0x55e32383c928"
y n’est pas une copie de x.x et y sont des références à l’objet de type vecteur c(1, 2, 3).
dispose d’un ensemble de règles pour les noms utilisables :
Contient uniquement des lettres (ASCII, mais pas uniquement), des chiffres, . et _.
Ne peut pas débuter par des chiffres ou _.
Ne peut pas être un “nom réservé” (?Reserved).
_abc <- 1
#> Error: <text>:1:1: unexpected input #> 1: _ #> ^
TRUE <- "false"
#> Error in TRUE <- "false": invalid (do_set) left-hand side to assignment
`_abc` <- 1
`+` <- 1
Expliquer les relations entre a, b, c, d et e.
a <- 1:10 b <- a c -> b e <- d <- 1:10
Que donne le code suivant pour importer un “fichier” csv ? Quel argument faudrait-il utiliser pour avoir les noms des colonnes tels-qu’ils sont ?
read.csv( header = TRUE, text = "1ere_colonne,deuxième_colonne,troisième colonne\n1,2,3" )
Les fonctions read.*() utilisent make.names() ? Quels sont les règles de conversions utilisées ?
x <- c(1, 2, 3) y <- x y[3] <- 4 x
#> [1] 1 2 3
y
#> [1] 1 2 4
La modification de y n’a pas modifié x.
crée une copie de l’objet référencé par x en modifiant la troisème valeur.
Ce nouvel objet est ensuite référencé par y.
x <- 1:3 x <- 2:4 rm(x) # Déréférencement gc() # Force "Garbage Collection"
#> used (Mb) gc trigger (Mb) max used (Mb) #> Ncells 678973 36.3 1217815 65.1 1217815 65.1 #> Vcells 1203464 9.2 8388608 64.0 2209326 16.9
À partir du data.framesuivant, créer une colonne nommée “3” comme la somme des colonnes 1 et 2 en utilisant l’opérateur $.
df <- data.frame(runif(3), runif(3)) names(df) <- c(1, 2)
À quelle ligne, une copie de a est effectuée ?
a <- c(1, 5, 3, 2) b <- a b[[1]] <- 10
TRUE et FALSE.0.1234.1.23e4.0xcafe.Inf, -Inf et NaN.L, p.ex., 123L, 1.23e4L et 0xcafeL." ou '.\ (?Quotes).c() (“combine”) permet de constituer des vecteurs de longueurs supérieurs à 1.
lgl_var <- c(TRUE, FALSE)
int_var <- c(1L, 6L, 10L)
dbl_var <- c(1, 2.5, 4.5)
chr_var <- c("these are", "some strings")
Lorsque les éléments de c() sont dit atomiques, le résultat est alors de même nature.
c(c(1, 2), c(3, 4))
#> [1] 1 2 3 4
Le type d’un vecteur peut-être déterminé via typeof().
typeof(lgl_var)
#> [1] "logical"
typeof(int_var)
#> [1] "integer"
typeof(dbl_var)
#> [1] "double"
typeof(chr_var)
#> [1] "character"
Et sa longueur via length().
length(lgl_var)
#> [1] 2
length(int_var)
#> [1] 3
length(dbl_var)
#> [1] 3
length(chr_var)
#> [1] 2
symbolise les valeurs manquantes à l’aide de NA (not applicable).
Un calcul impliquant NA résultera en un NA.
NA > 5
#> [1] NA
10 * NA
#> [1] NA
!NA
#> [1] NA
À quelques exceptions.
NA ^ 0
#> [1] 1
NA | TRUE
#> [1] TRUE
NA & FALSE
#> [1] FALSE
Détermination des valeurs manquantes d’un vecteur de façon “naïve”.
x <- c(NA, 5, NA, 10) x == NA
#> [1] NA NA NA NA
La bonne approche pour éviter les erreurs.
is.na(x)
#> [1] TRUE FALSE TRUE FALSE
NA est la forme “générique”, mais il existe un NA pour chacun des types :
NA.NA_real_.NA_integer_.NA_character_. dispose de fonctions is.*() pour tester le type d’un vecteur, mais sont à utiliser avec précautions.
is.logical(), is.integer(), is.double() et is.character() effectueront bien le test demandé/attendu.
Ce qui ne sera pas nécessairement le cas de is.vector(), is.atomic() et is.numeric().
?is.numeric
is.numeric is an internal generic primitive function: you can write methods to handle specific classes of objects, see InternalMethods. It is not the same as is.double. Factors are handled by the default method, and there are methods for classes “Date”, “POSIXt” and “difftime” (all of which return false). Methods for is.numeric should only return true if the base type of the class is double or integer and values can reasonably be regarded as numeric (e.g., arithmetic on them makes sense, and comparison should be done via the base type).
Un vecteur ne dispose que d’un seul type, c’est-à-dire, tous les éléments doivent avoir le même type.
Lorsque les éléments d’un vecteur sont de plusieurs types, une conversion sera appliquée selon la règle de priorité :character → double → integer → logical.
x <- c("a", 1)
typeof(x)
#> [1] "character"
str(x)
#> chr [1:2] "a" "1"
La plupart des fonctions mathématiques réalise cette conversion de type (p.ex., +, log, etc.).
x <- c(FALSE, FALSE, TRUE) as.numeric(x)
#> [1] 0 0 1
# Nombre de "TRUE" sum(x)
#> [1] 1
# Proportion de "TRUE" mean(x)
#> [1] 0.3333333
Il est possible de convertir explicitement un vecteur avec les fonctions as.*() : as.logical(), as.integer(), as.double() et as.character().
avertira via un avertissement d’un problème lors de la conversion.
as.integer(c("1", "1.5", "a"))
#> Warning: NAs introduced by coercion
#> [1] 1 1 NA
Déterminer le type des vecteurs suivants.
c(1, FALSE)
c("a", 1)
c(TRUE, 1L)Déterminer le résultat des comparaisons suivantes.
1 == "1" -1 < FALSE "one" < 2
Pour quelle raison ces résultats ont été obtenu ?
Pourquoi le type par défaut de NA est booléen ?
Les attributs sont des meta-données stockées sont la forme de paire nom/valeur.
Chaque attribut peut être récuperé et défini individuellement via attr(), récupéré en masse via attributes() ou encore défini en masse via structure().
a <- 1:3 attr(a, "x") <- "abcdef" attr(a, "x")
#> [1] "abcdef"
attr(a, "y") <- 4:6 str(attributes(a))
#> List of 2 #> $ x: chr "abcdef" #> $ y: int [1:3] 4 5 6
a <- structure( 1:3, x = "abcdef", y = 4:6 ) str(attributes(a))
#> List of 2 #> $ x: chr "abcdef" #> $ y: int [1:3] 4 5 6
Les attributs sont en général éphémères, dans le sens où ils sont perdus dans la plupart des opérations.
attributes(a[1])
#> NULL
attributes(sum(a))
#> NULL
Là encore, il y a principalement deux exceptions :
names), un vecteur de chaîne de caractères donnant le nom de chaque élément.dim), un vecteur de valeurs entières donnant les dimensions (utilisé dans la conversion des vecteurs en matrices ou “arrays”).Il existe plusieurs façons de nommer les éléments d’un vecteur.
Lors de la création.
x <- c(a = 1, b = 2, c = 3)
Avec names() pour affecter des un vecteur de chaîne de caractères.
x <- 1:3
names(x) <- c("a", "b", "c")Avec setNames(), pour réaliser la même tâche en une seule ligne.
x <- setNames(1:3, c("a", "b", "c"))Les vecteurs sont de dimension NULL.
dim(1:6)
#> NULL
Les matrices sont de dimension 2.
x <- matrix(1:6, nrow = 2, ncol = 3) dim(x)
#> [1] 2 3
Les “arrays” sont de dimension n.
x <- array(1:12, dim = c(2, 3, 2)) dim(x)
#> [1] 2 3 2
Il est possible de modifier directement les dimensions d’un vecteur pour en modifier la “forme”.
x <- 1:6 dim(x) <- c(3, 2) x
#> [,1] [,2] #> [1,] 1 4 #> [2,] 2 5 #> [3,] 3 6
| Vector | Matrix | Array |
|---|---|---|
| names() | rownames(), colnames() | dimnames() |
| length() | nrow(), ncol() | dim() |
| c() | rbind(), cbind() | abind::abind() |
| --- | t() | aperm() |
| is.null(dim(x)) | is.matrix() | is.array() |
str() est le meilleur moyen d’identifier la “nature” d’un objet.
str(1:3) # 1d vector
#> int [1:3] 1 2 3
str(matrix(1:3, ncol = 1)) # column vector
#> int [1:3, 1] 1 2 3
str(matrix(1:3, nrow = 1)) # row vector
#> int [1, 1:3] 1 2 3
str(array(1:3, 3)) # "array" vector
#> int [1:3(1d)] 1 2 3
class est un autre attribut important dans , il est le fondement du sytème objet S3.
Un objet possédant l’attribut class devient un objet S3 qui réagira différemment d’un simple objet au regard d’une fonction dite “générique”.
Les principaux vecteurs S3 :
factor, permettant de définir des niveaux pour un vecteur.Date, la date dans un format défini au jour près.POSIXct, la date dans un format défini à la seconde près.Un facteur est un vecteur ne pouvant contenir que des valeurs prédéfinies.
Ce type de vecteur est utilisé pour stocker des données catégorielles / discrètesen se basant sur un vecteur d’entier.
x <- factor(c("a", "b", "b", "a"))
x
#> [1] a b b a #> Levels: a b
typeof(x)
#> [1] "integer"
Un facteur est un vecteur ne pouvant contenir que des valeurs prédéfinies.
Ce type de vecteur est utilisé pour stocker des données catégorielles / discrètesen se basant sur un vecteur d’entier.
attributes(x)
#> $levels #> [1] "a" "b" #> #> $class #> [1] "factor"
str(x)
#> Factor w/ 2 levels "a","b": 1 2 2 1
Les niveaux d’un facteur peuvent être connus, mais pas nécessairement observés dans les données.
sex_char <- c("m", "m", "m")
sex_factor <- factor(sex_char, levels = c("m", "f"))
Ainsi, il est possible de compter les occurences de l’ensemble des niveaux.
table(sex_char)
#> sex_char #> m #> 3
table(sex_factor)
#> sex_factor #> m f #> 3 0
Les facteurs peuvent également être ordonnées et se comportent comme des facteurs “classiques”.
ordered(c("b", "b", "a", "c"), levels = c("c", "b", "a"))
#> [1] b b a c #> Levels: c < b < a
factor( c("b", "b", "a", "c"), levels = c("c", "b", "a"), ordered = TRUE)
#> [1] b b a c #> Levels: c < b < a
Note : Les fonctions read.*() et data.frame() convertissent automatique les vecteurs de chaîne de caractères en facteurs. Il est recommandé de désactiver ce comportant options(stringsAsFactors = FALSE) (Par défaut avec R > 4.0).
Quelle sorte d’objet renvoi table() ? Quel est son type ? Quels sont ses attributs ?
Qu’arrive-t-il à un facteur lorsque les niveaux sont modifiés ?
f1 <- factor(letters) levels(f1) <- rev(levels(f1))
Que fait le code suivant ? De quelle façon f2 et f3 différent-ils de f1 ?
f2 <- rev(factor(letters)) f3 <- factor(letters, levels = rev(letters))
À la différence des vecteurs, les éléments d’une liste peuvent être de n’importe quel type, il n’est plus question de “cohérence de type”.
l1 <- list( 1:3, "a", c(TRUE, FALSE, TRUE), c(2.3, 5.9) ) typeof(l1)
#> [1] "list"
À la différence des vecteurs, les éléments d’une liste peuvent être de n’importe quel type, il n’est plus question de “cohérence de type”.
str(l1)
#> List of 4 #> $ : int [1:3] 1 2 3 #> $ : chr "a" #> $ : logi [1:3] TRUE FALSE TRUE #> $ : num [1:2] 2.3 5.9
Chaque élément d’une liste, n’est en réalité qu’une référence à l’objet.
lobstr::obj_size(mtcars)
#> 7,208 B
l2 <- list(mtcars, mtcars, mtcars, mtcars) lobstr::obj_size(l2)
#> 7,288 B
La levée de la contrainte de “cohérence de type” fait des listes un type particulièrement flexible et de ce fait ne permet pas d’avoir une représentation générique efficace systématiquement, comme c’est le cas pour les vecteurs.
l3 <- list(list(list(1))) str(l3)
#> List of 1 #> $ :List of 1 #> ..$ :List of 1 #> .. ..$ : num 1
c() permet de combiner des éléments dans le cas des listes.
l4 <- list(list(1, 2), c(3, 4)) str(l4)
#> List of 2 #> $ :List of 2 #> ..$ : num 1 #> ..$ : num 2 #> $ : num [1:2] 3 4
l5 <- c(list(1, 2), c(3, 4)) str(l5)
#> List of 4 #> $ : num 1 #> $ : num 2 #> $ : num 3 #> $ : num 4
Le typeof() d’une liste est list. is.list() permet de tester si l’objet est une liste quand as.list() permet la conversion en liste.
list(1:3)
#> [[1]] #> [1] 1 2 3
as.list(1:3)
#> [[1]] #> [1] 1 #> #> [[2]] #> [1] 2 #> #> [[3]] #> [1] 3
L’attribut dim permettait de passer d’un vecteur à une matrice ou à un array.
Dans le cas des listes, il permet de passer à des “matrice-liste” et “array-liste”.
l <- list(1:3, "a", TRUE, 1.0) dim(l) <- c(2, 2) l
#> [,1] [,2] #> [1,] Integer,3 TRUE #> [2,] "a" 1
l[[1, 1]]
#> [1] 1 2 3
Lister les points de divergences entre un vecteur et une liste.
Pourquoi as.vector() ne fonctionne pas pour convertir une liste en vecteur ? Pourquoi l’usage de unlist() est nécessaire ?
data.frameL’une des classes S3 importante dans est la classe data.frame (tibble dans le “tidyverse”), qui repose entièrement sur les listes.
Qu’est-ce qu’un data.frame ?
Un data.frame est une liste nommée, de vecteur de même dimension (longueur) avec des attributs names (noms des colonnes) et row.names.
df1 <- data.frame(x = 1:3, y = letters[1:3]) typeof(df1)
#> [1] "list"
data.frameL’une des classes S3 importante dans est la classe data.frame (tibble dans le “tidyverse”), qui repose entièrement sur les listes.
Qu’est-ce qu’un data.frame ?
Un data.frame est une liste nommée, de vecteur de même longueur avec des attributs names (noms des colonnes) et row.names.
attributes(df1)
#> $names #> [1] "x" "y" #> #> $class #> [1] "data.frame" #> #> $row.names #> [1] 1 2 3
data.frameUn data.frame a donc une structure rectangulaire et dispose de noms pour les lignes et les colonnes.
rownames() pour obtenir le noms des lignes.colnames() (ou names()) pour obtenir le noms des colonnes.nrow() pour obtenir le nombre de lignes.ncol() (ou length()) pour obtenir le nombre de colonnes.data.frameLa création d’un data.frame se fait via data.frame().
df <- data.frame(
x = 1:3,
y = c("a", "b", "c")
)
str(df)
#> 'data.frame': 3 obs. of 2 variables: #> $ x: int 1 2 3 #> $ y: chr "a" "b" "c"
data.frameLa création d’un data.frame se fait via data.frame().
df <- data.frame(
x = 1:3,
y = c("a", "b", "c"),
stringsAsFactors = TRUE # Par défaut dans R < 4.0
)
str(df)
#> 'data.frame': 3 obs. of 2 variables: #> $ x: int 1 2 3 #> $ y: Factor w/ 3 levels "a","b","c": 1 2 3
data.frameLa création d’un data.frame se fait via data.frame().
df <- data.frame(
x = 1:3,
y = c("a", "b", "c"),
stringsAsFactors = FALSE # Par défaut dans R > 4.0
)
str(df)
#> 'data.frame': 3 obs. of 2 variables: #> $ x: int 1 2 3 #> $ y: chr "a" "b" "c"
data.framePar défaut, un data.frame requiert des noms de colonnes syntaxiquement correct.
names(data.frame(`1` = 1))
#> [1] "X1"
names(data.frame(`1` = 1, check.names = FALSE))
#> [1] "1"
data.frameUn data.frame requiert que ces éléments soit de même longueur, quand cela n’est pas respecté et lorsque c’est possible, les valeurs des vecteurs les plus courts sont recyclés.
data.frame(x = 1:4, y = 1:2)
#> x y #> 1 1 1 #> 2 2 2 #> 3 3 1 #> 4 4 2
data.frame(x = 1:4, y = 1:3)
#> Error in data.frame(x = 1:4, y = 1:3): arguments imply differing number of rows: 4, 3
data.frameLes data.frame ayant des noms de lignes, il est possible de les définir de plusieurs façons.
df3 <- data.frame(
age = c(35, 27, 18),
hair = c("blond", "brown", "black"),
row.names = c("Bob", "Susan", "Sam")
)
df3
#> age hair #> Bob 35 blond #> Susan 27 brown #> Sam 18 black
data.frameLes data.frame ayant des noms de lignes, il est possible de les définir de plusieurs façons.
df3 <- data.frame(
age = c(35, 27, 18),
hair = c("blond", "brown", "black")
)
rownames(df3) <- c("Bob", "Susan", "Sam")
df3
#> age hair #> Bob 35 blond #> Susan 27 brown #> Sam 18 black
data.frameL’usage des noms de lignes n’est pas recommandé.
Le nom des lignes est une donnée, pourquoi la stocker différemment ?
Le nom des lignes doit obligatoirement être une chaîne de caractères.
Chaque nom de ligne doit-être unique. s’assurera que ce soit le cas !
df3[c(1, 1, 1), ]
#> age hair #> Bob 35 blond #> Bob.1 35 blond #> Bob.2 35 blond
is.data.frame() permet de tester si l’objet est un data.frame() quand as.data.frame() permet la conversion.
is.data.frame(df1)
#> [1] TRUE
Est-il possible d’avoir un data.frame avec zéro lignes ? Et zéro colonnes ?
Que se passe-t-il lorsque des noms lignes avec duplicats sont définis via rownames() ?
Que donne t(df) ou t(t(df)) ? Avec, df un objet de classe data.frame.
Que fait as.matrix() sur un data.frame dont les colonnes sont de type différents ?
NULLNULL un objet particulier.
typeof(NULL)
#> [1] "NULL"
length(NULL)
#> [1] 0
x <- NULL attr(x, "y") <- 1
#> Error in attr(x, "y") <- 1: attempt to set an attribute on NULL
NULLIl est possible de tester le caractère NULL d’un objet.
is.null(NULL)
#> [1] TRUE
NULL sert à définir :
un vecteur vide (p.ex., c().
un vecteur absent (p.ex., argument non défini d’une fonction).
x <- c(2.1, 4.2, 3.3, 5.4)
x[c(3, 1)]
#> [1] 3.3 2.1
x[c(1, 1)]
#> [1] 2.1 2.1
x[c(2.1, 2.9)] # Troncature
#> [1] 4.2 4.2
x <- c(2.1, 4.2, 3.3, 5.4)
x[-c(3, 1)]
#> [1] 4.2 5.4
x[c(-1, 2)] # Pas de mélange
#> Error in x[c(-1, 2)]: only 0's may be mixed with negative subscripts
x <- c(2.1, 4.2, 3.3, 5.4)
x[c(TRUE, TRUE, FALSE, FALSE)]
#> [1] 2.1 4.2
x[x > 3]
#> [1] 4.2 3.3 5.4
x <- c(2.1, 4.2, 3.3, 5.4)
x[c(TRUE, FALSE)] # Recyclage
#> [1] 2.1 3.3
x[c(TRUE, FALSE, TRUE, FALSE)]
#> [1] 2.1 3.3
x <- c(2.1, 4.2, 3.3, 5.4)
x[c(TRUE, TRUE, NA, FALSE)]
#> [1] 2.1 4.2 NA
x <- c(2.1, 4.2, 3.3, 5.4)
x[]
#> [1] 2.1 4.2 3.3 5.4
x <- c(2.1, 4.2, 3.3, 5.4)
x[0]
#> numeric(0)
x <- c(2.1, 4.2, 3.3, 5.4) names(x) <- letters[1:4]
x[c("d", "c", "a")]
#> d c a #> 5.4 3.3 2.1
x[c("a", "a", "a")]
#> a a a #> 2.1 2.1 2.1
z <- c(abc = 1, def = 2)
z[c("a", "d")] # Correspondance parfaite
#> <NA> <NA> #> NA NA
z[c("abc", "def")]
#> abc def #> 1 2
La sélection s’opère de la même façon que sur un vecteur.
[, renvoi une liste.[[ et $, renvoient un élément d’une liste.La sélection s’opère de la même façon que sur un vecteur.
[, renvoi une liste.
x <- list(2.1, 4.2, 3.3, 5.4) x[c(1, 3)]
#> [[1]] #> [1] 2.1 #> #> [[2]] #> [1] 3.3
x[[2]]
#> [1] 4.2
La sélection s’opère de la même façon que sur un vecteur.
[[ et $, renvoient un élément d’une liste.
x <- list(2.1, 4.2, 3.3, 5.4) names(x) <- letters[1:4] x$a
#> [1] 2.1
x[["b"]]
#> [1] 4.2
La sélection peut s’effectuer avec un vecteur, plusieurs vecteurs ou une matrice.
a <- matrix(1:9, nrow = 3)
colnames(a) <- c("A", "B", "C")
a[1:2, ]
#> A B C #> [1,] 1 4 7 #> [2,] 2 5 8
a[c(TRUE, FALSE, TRUE), c("B", "A")]
#> B A #> [1,] 4 1 #> [2,] 6 3
Comme les matrices ou arrays ne sont que des vecteurs avec un attribut dim, la sélection peut se faire directement avec un seul vecteur de position.
vals <- outer(1:5, 1:5, FUN = "paste", sep = ",") vals
#> [,1] [,2] [,3] [,4] [,5] #> [1,] "1,1" "1,2" "1,3" "1,4" "1,5" #> [2,] "2,1" "2,2" "2,3" "2,4" "2,5" #> [3,] "3,1" "3,2" "3,3" "3,4" "3,5" #> [4,] "4,1" "4,2" "4,3" "4,4" "4,5" #> [5,] "5,1" "5,2" "5,3" "5,4" "5,5"
vals[c(4, 15)]
#> [1] "4,1" "5,3"
Il est également possible d’effectuer la sélection à partir d’une matrice donnant la position des dans chacune des dimensions de la matrice ou array que l’on souhaite manipuler.
vals <- outer(1:5, 1:5, FUN = "paste", sep = ",") select <- matrix(ncol = 2, byrow = TRUE, c( 1, 1, 3, 1, 2, 4 )) vals[select]
#> [1] "1,1" "3,1" "2,4"
data.frameLes data.frame se comportent comme des listes et comme des matrices.
df <- data.frame(x = 1:3, y = 3:1, z = letters[1:3]) df[df$x == 2, ]
#> x y z #> 2 2 2 b
df[c(1, 3), ]
#> x y z #> 1 1 3 a #> 3 3 1 c
data.frameDeux approches pour sélectionner les colonnes d’un data.frame.
df <- data.frame(x = 1:3, y = 3:1, z = letters[1:3])
df[c("x", "z")] # approche liste
#> x z #> 1 1 a #> 2 2 b #> 3 3 c
df[, c("x", "z")] # approche matrice
#> x z #> 1 1 a #> 2 2 b #> 3 3 c
data.frameAttention, ces deux approches ne sont pas tout à fait équivalentes.
str(df["x"])
#> 'data.frame': 3 obs. of 1 variable: #> $ x: int 1 2 3
str(df[, "x"])
#> int [1:3] 1 2 3
str(df[, "x", drop = FALSE])
#> 'data.frame': 3 obs. of 1 variable: #> $ x: int 1 2 3
Corriger les erreurs dans les codes suivants.
mtcars[mtcars$cyl = 4, ] mtcars[-1:4, ] mtcars[mtcars$cyl <= 5] mtcars[mtcars$cyl == 4 | 6, ]
Pourquoi le code suivant renvoi cinq valeurs manquantes ? Et avec x[NA_real_] ?
x <- 1:5 x[NA]
#> [1] NA NA NA NA NA
Pourquoi mtcars[1:20] génére une erreur alors que mtcars[1:20, ] fonctionne ? Quelle est la différence ?
Que fait df[is.na(df)] <- 0 ? Sur quel principe repose cette commande ?
[[ et $[[ renvoi toujours un élément plus petit.
x <- list(1:3, "a", 4:6) x[1]
#> [[1]] #> [1] 1 2 3
x[[1]]
#> [1] 1 2 3
[[ et $$ fonctionne d’une façon proche de celle de [[.
mitcars$cyl mitcars[["cyl"]]
[[ et $Le $ n’est pas utilisable lorsque le nom de la colonne ou de l’élément est stockée dans une variable.
var <- "cyl" mtcars$var
#> NULL
mtcars[[var]]
#> [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
[[ et $L’opérateur $ permet également une correspondance partiel des noms, contrairement à [[ (ou [).
x <- list(abc = 1) x$a
#> [1] 1
x[["a"]]
#> NULL
slot() et @Les opérateurs slot() et @ sont des opérateurs spécifiques des objets de classe S4, ou slot() correspond à [[ et @ à $.
Extraire la troisième valeur de la variable cyl du jeu de données mtcars.
À partir de la régression linéaire mod <- lm(mpg ~ wt, data = mtcars), extraire le nombre de degré de liberté. Puis extraire, le R carré du modèle (summary(mod)).
Les opérateurs [, [[ et $ permettent également les affectations ou modifications.
x <- 1:5 x[c(1, 2)] <- c(101, 102) x
#> [1] 101 102 3 4 5
Attention au recyclage des valeurs !
Approche identique pour les listes.
x <- list(a = 1, b = 2) x[["b"]] <- NULL y <- list(a = 1, b = 2) y["b"] <- list(NULL) str(y)
#> List of 2 #> $ a: num 1 #> $ b: NULL
Le cas de la sélection par “rien”, c’est-à-dire, df[], permet dans le cas d’une affectation de préservé la structure d’origine.
mtcars[] <- lapply(mtcars, as.integer) is.data.frame(mtcars)
#> [1] TRUE
mtcars <- lapply(mtcars, as.integer) is.data.frame(mtcars)
#> [1] FALSE
Ajouter une colonne cyl_fct à mtcars comme une copie de la colonne cyl. Quel est le type de la nouvelle colonne ? Modifier le type de cette colonne dans un type plus approprié pour une analyse de comparaison de groupes défini par cyl_fct.
Reprendre les fonctions vu au préalable et identifier la structure, le type, la classe et les attributs des objets générés par ces fonctions, p.ex., stats::lm(), stats::aov(), t.test(), ggplot2::ggplot(), etc.
Manipuler les fonctions str(), typeof(), dput(), attributes(), attr(), dimnames(), dim(), rownames(), colnames() et names() sur les jeux de données de datasets (ls(name = "package:datasets")).
Créer une liste, un vecteur, un data.frame à l’aide de la fonction structure().